package org.wsiz.vro.domain;

import static javax.persistence.CascadeType.PERSIST;
import static javax.persistence.FetchType.LAZY;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.persistence.Version;
import javax.xml.bind.annotation.XmlTransient;

import org.apache.log4j.Logger;
import org.springframework.data.domain.Persistable;

import com.google.common.base.Objects;

/**
 * @author "Tomasz Marciniak"
 */
@Entity
@Table(name = "film")
public class Inventory implements Persistable<Integer> {
	private static final long serialVersionUID = 1L;

	@SuppressWarnings("unused")
	private static final Logger log = Logger.getLogger(Inventory.class);

	private Integer id;
	private Integer filmId;
	private Double price;

	private Film film;

	public Inventory() {
	}

	public Inventory(Integer primaryKey) {
		setId(primaryKey);
	}

	@Override
	@Transient
	@XmlTransient
	public boolean isNew() {
		return getId() == null;
	}

	@Column(nullable = false, unique = true, precision = 10)
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Id
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	@JoinColumn(name = "film_id")
	@ManyToOne(cascade = PERSIST, fetch = LAZY)
	public Film getFilm() {
		return film;
	}

	/**
	 * Set the film without adding this Book instance on the passed film If you
	 * want to preserve referential integrity we recommend to use instead the
	 * corresponding adder method provided by {@link Film}
	 */
	public void setFilm(Film film) {
		this.film = film;

		// We set the foreign key property so it can be used by Hibernate search
		// by Example facility.
		if (film != null) {
			setFilmId(film.getId());
		} else {
			setFilmId(null);
		}
	}

	@Column(name = "film_id", length = 32, insertable = false, updatable = false)
	public Integer getFilmId() {
		return filmId;
	}

	private void setFilmId(Integer filmId) {
		this.filmId = filmId;
	}

	@Column(precision = 10)
	@Version
	public Double getPrice() {
		return price;
	}

	public void setPrice(Double price) {
		this.price = price;
	}

	/**
	 * Set the default values.
	 */
	public void initDefaultValues() {
	}

	@Override
	public boolean equals(Object other) {
		return this == other
				|| (other instanceof Inventory && hashCode() == other
						.hashCode());
	}

	private PersistableHashBuilder persistableHashBuilder = new PersistableHashBuilder();

	@Override
	public int hashCode() {
		return persistableHashBuilder.hash(this);
	}

	/**
	 * Construct a readable string representation for this {@link Inventory}
	 * instance.
	 */
	@Override
	public String toString() {
		return Objects.toStringHelper(this) //
				.add("id", getId()) //
				.add("film_id", getFilmId()) //
				.add("price", getPrice()) //
				.toString();
	}
}